#include "Manager.hpp"

using namespace luabind;
namespace bind
{
	namespace SL
	{
		namespace manager
		{
			template <class M> void BSpecific(lua_State* lua, const std::string& ns, const std::string& name)//, std::tr1::function<sl::tmp::ManagerTemplate<M>* (sl::tmp::ManagerTemplate<M>*)> templatefkt)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::ManagerTemplate<M> >(std::string(name + "Manager").c_str())
							.def(constructor<>())
							.def("Insert", (M*(sl::tmp::ManagerTemplate<M>::*)(const std::string&, const M&))&sl::tmp::ManagerTemplate<M>::Insert)
							.def("Insert", (M*(sl::tmp::ManagerTemplate<M>::*)(const std::string&))&sl::tmp::ManagerTemplate<M>::Insert)
							.def("Delete", &sl::tmp::ManagerTemplate<M>::Delete)
							.def("Get", &sl::tmp::ManagerTemplate<M>::Get)
							.def("Clear", &sl::tmp::ManagerPointer<M>::Clear)
					];

				//globals(lua)[ns.c_str()][std::string(name + "Manager").c_str()] = templatefkt;
			}

			template <class M> void BPointer(lua_State* lua, const std::string& ns, const std::string& name)//, std::tr1::function<sl::tmp::ManagerPointer<M>* (sl::tmp::ManagerPointer<M>*)> pointerfkt)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::ManagerPointer<M> >(std::string(name + "Manager").c_str())
							.def(constructor<>())
							.def("Insert", &sl::tmp::ManagerPointer<M>::Insert)
							.def("Delete", &sl::tmp::ManagerPointer<M>::Delete)
							.def("Get", &sl::tmp::ManagerPointer<M>::Get)
							.def("Clear", &sl::tmp::ManagerPointer<M>::Clear)
					];

				//globals(lua)[ns.c_str()][std::string(name + "Manager").c_str()] = pointerfkt;
			}

			void BScriptManager(lua_State* lua, const std::string& ns)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::ScriptManagerS, bases<sl::tmp::ManagerTemplate<std::string> > >("ScriptManager")
							.def(constructor<>())
							.def("Start", &sl::tmp::ScriptManagerS::Start)
					];
			}

			void BTextureManager(lua_State* lua, const std::string& ns)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::TextureManagerS, bases<sl::tmp::ManagerTemplate<sf::Texture> > >("TextureManager")
							.def(constructor<>())
							.def("LoadFromFile", &sl::tmp::TextureManagerS::LoadFromFile)
					];
			}

			void BAnimationManager(lua_State* lua, const std::string& ns)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::AnimationManagerS, bases<sl::tmp::ManagerPointer<sl::Animation> > >("AnimationManager")
							.def(constructor<>())
							.def("Update", &sl::tmp::AnimationManagerS::Update)
							.def("Draw", &sl::tmp::AnimationManagerS::Draw)
					];
			}

			void BDirAnimationManager(lua_State* lua, const std::string& ns)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::DirAnimationManagerS, bases<sl::tmp::ManagerPointer<sl::DirAnimation> > >("DirAnimationManager")
							.def(constructor<>())
							.def("Update", &sl::tmp::DirAnimationManagerS::Update)
							.def("Draw", (sl::tmp::DirAnimationManagerS*(sl::tmp::DirAnimationManagerS::*)(sf::RenderTexture*))&sl::tmp::DirAnimationManagerS::Draw)
							.def("Draw", (sl::tmp::DirAnimationManagerS*(sl::tmp::DirAnimationManagerS::*)(sf::RenderTexture*, sf::Shader&))&sl::tmp::DirAnimationManagerS::Draw)
					];
			}

			void BRenderTextureManager(lua_State* lua, const std::string& ns)
			{
				module(lua, ns.c_str())
					[
						class_<sl::tmp::RenderTextureManagerS, bases<sl::tmp::ManagerPointer<sf::RenderTexture> > >("RenderTextureManager")
							.def("Create", &sl::tmp::RenderTextureManagerS::Create)
							.def("Clear", (sl::tmp::RenderTextureManagerS*(sl::tmp::RenderTextureManagerS::*)(const sf::Color&))&sl::tmp::RenderTextureManagerS::Clear)
							.def("Clear", (sl::tmp::RenderTextureManagerS*(sl::tmp::RenderTextureManagerS::*)(const std::string&, const sf::Color&))&sl::tmp::RenderTextureManagerS::Clear)
							.def("Display", (sl::tmp::RenderTextureManagerS*(sl::tmp::RenderTextureManagerS::*)(const std::string&))&sl::tmp::RenderTextureManagerS::Display)
							.def("Display", (sl::tmp::RenderTextureManagerS*(sl::tmp::RenderTextureManagerS::*)())&sl::tmp::RenderTextureManagerS::Display)
							.def("Draw", (sl::tmp::RenderTextureManagerS*(sl::tmp::RenderTextureManagerS::*)(const std::string&, sf::RenderTarget*, float, float))&sl::tmp::RenderTextureManagerS::Draw)
							.def("Draw", (sl::tmp::RenderTextureManagerS*(sl::tmp::RenderTextureManagerS::*)(sf::RenderTarget*, float, float))&sl::tmp::RenderTextureManagerS::Draw)
							.def("SetActive", &sl::tmp::RenderTextureManagerS::SetActive)
							.def("IsActive", &sl::tmp::RenderTextureManagerS::IsActive)
					];
			}

			void Bind(lua_State* lua, const std::string& ns)
			{
				open(lua);
				MManagerPointer(sl::Log, Log);
				MManager(Log);
				//sl::Lua->Execute("print = function(msg) sl.LogManager:Get('stdout'):Write(tostring(msg)) end");
				MManagerTemplate(std::string, Folder);
				MManager(Folder);

				MManagerTemplate(std::string, tmp);
				BScriptManager(lua, ns); MManager(Script);
				MManagerTemplate(sf::Texture, tmp);
				BTextureManager(lua, ns); MManager(Texture);
				MManagerPointer(sl::Animation, tmp);
				BAnimationManager(lua, ns); MManager(Animation);
				MManagerPointer(sl::DirAnimation, tmp);
				BDirAnimationManager(lua, ns); MManager(DirAnimation);
				/*MManagerPointer(sl::Animation, tmp);
				BRenderTextureManager(lua, ns); MManager(RenderTexture);*/
			}
		}
	}
}